package munci.old.know.words;

import java.util.LinkedList;

import munci.old.use.Try;


public abstract class Word implements Executable {

	/**
	 * Every class that contains Words must define the following field:
	 * <pre>
	 * public static final Word.List WORDS;
	 * </pre>
	 * @author Giles Burgess
	 *
	 */
	public static class Book {
		private Class<?> source;
		private LinkedList<Word> list;
		
		public Book(Class<?> source, Word... words) {
			this.list = new LinkedList<Word>();
			this.source = source;
			add(words);
		}
		
		public Book add(Word... words) {
			for (Word word : words) {
				word.owner = source;
				word.index = list.size();
				list.add(word);
			}
			return this;
		}
		
		public Class<?> source() {
			return source;
		}
		
		public Word[] toArray() {
			return list.toArray(new Word[0]);
		}
	}

	/**
	 * Word.words(x.owner())[x.index()] == x
	 * @param cl
	 * @return
	 */
	public static Word[] words(Class<?> cl) {
		try {
			return (Word[]) Try.get(cl.getDeclaredField("WORDS"), null);
		} catch (NoSuchFieldException e1) {
			return new Word[0];
		}
	}

	public final String name;
	
	private Class<?> owner = null;
	private int index;
	
	public Word(String name) {
		this.name = name;
	}
	
	public final Class<?> owner() {
		return owner;
	}
	
	public final int index() {
		return index;
	}

	@Override public String toString() {
		return '"' + name + '"';
	}
}
